﻿using System;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Ink;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using System.Windows.Threading;
using System.Collections.Generic;

namespace exsportance.Silverlight.Common.Helpers
{
    public static class DoubleClickHelper
    {
        #region members
        private static Dictionary<FrameworkElement, DoubleClickItem> _list = new Dictionary<FrameworkElement, DoubleClickItem>();
        #endregion

        /// <summary>
        /// Delegate definition for the call back function.
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        public delegate void DoubleClickHandler(object sender, MouseButtonEventArgs e);

        #region public methods
        /// <summary>
        /// Register for double click check
        /// </summary>
        /// <param name="control"></param>
        /// <param name="doubleClickHandler"></param> 
        public static void RegisterDoubleClick(this FrameworkElement control, DoubleClickHandler doubleClickHandler)
        {
            RegisterDoubleClick(control, doubleClickHandler, 200);
        }

        /// <summary>
        /// Register for double click check
        /// </summary>
        /// <param name="control"></param>
        /// <param name="doubleClickHandler"></param> 
        /// <param name="doubleClickInterval">The interval between the two click, in milliseconds.</param>
        public static void RegisterDoubleClick(this FrameworkElement control, DoubleClickHandler doubleClickHandler, int doubleClickInterval)
        {
            DoubleClickItem item = new DoubleClickItem();

            // create the  timer
            item.Timer = new DispatcherTimer();
            item.Timer.Interval = new TimeSpan(0, 0, 0, 0, doubleClickInterval);
            item.Timer.Tick += (s, e) => { item.Timer.Stop(); item.HasDoubleClicked = false; };

            // create event handler
            item.EventHandler = (s, e) =>
            {
                // if it's 2nd time, check if timer is started
                if (item.Timer.IsEnabled)
                {
                    // timer started, so a double click occured
                    item.Timer.Stop();
                    item.HasDoubleClicked = true;

                    // invoke delegate
                    if (doubleClickHandler != null)
                        doubleClickHandler(s, e);
                }
                else
                {
                    // timer not yet started -> start

                    item.HasDoubleClicked = false;
                    item.Timer.Start();
                }
            };

            // add event handler
            control.MouseLeftButtonDown += item.EventHandler;

            // add to list
            _list.Add(control, item);
        }

        /// <summary>
        /// Check if double click has occurred
        /// </summary>
        /// <param name="control"></param>
        /// <returns></returns>
        public static bool HasDoubleClicked(this FrameworkElement control)
        {
            if (_list.ContainsKey(control))
                return _list[control].HasDoubleClicked;
            else
                throw new Exception("Control was not registered for double click!");
        }

        /// <summary>
        /// Remove the double click check
        /// </summary>
        /// <param name="control"></param>
        public static void UnregisterDoubleClick(this FrameworkElement control)
        {
            if (_list.ContainsKey(control))
            {
                DoubleClickItem item = _list[control];

                // remove event handler
                control.MouseLeftButtonDown -= item.EventHandler;

                // dispose the timer
                item.Timer = null;

                // remove from list
                _list.Remove(control);
            }
            else
                throw new Exception("Control was not registered for double click!");
        }
        #endregion

    }

    internal class DoubleClickItem
    {
        public MouseButtonEventHandler EventHandler { get; set; }
        public DispatcherTimer Timer { get; set; }
        public bool HasDoubleClicked { get; set; }
    }
}
